﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace BlackBox.Models
{

    public class GameRepository
    {
        DataClassesDataContext db = new DataClassesDataContext();

        #region Singleton patern
        public static GameRepository instance;


        public static GameRepository Instance
        {
            get
            {
                if (instance == null)
                    instance = new GameRepository();
                return instance;
            }
        }
        #endregion 

        #region Get a Game by its Id
        public Game GetGameById(int id)
        {
            Game game = (from x in db.Games
                             where x.id == id
                             select x).SingleOrDefault();
            
            return game;
        }
        #endregion

        #region Get a Game by its Name
        public Game GetGameByName(string name)
        {
            Game game = (from x in db.Games
                             where x.name == name
                             select x).SingleOrDefault();
            
            return game;
        }
        #endregion

        #region Get All Games
        public IEnumerable<Game> GetAllGames()
        {
            var ListofGames = (from x in db.Games
                                      select x);
           
            return ListofGames;
        }
        #endregion

        #region Get All Games by Rating  
        public IEnumerable<Game> GetGameByRating(double toprating, double lowrating)
        {
            var ListofGames = from x in db.Games
                              where x.rating <= toprating && x.rating >= lowrating
                              select x;

          return ListofGames;
        }
        #endregion

        #region Get Games by Category
        public IEnumerable<Game> GetGameByCategory(int categoryId)
        {
            var idListofGames = from x in db.CategorytoGames
                                where x.categoryid == categoryId
                                   select x;
            List<Game> listofGames = new List<Game>();
            foreach (var newGames in idListofGames)
            {
                Game Temp = GetGameById(newGames.gameid);
                listofGames.Add(Temp);
            }
            var listofthings = listofGames;
            return listofthings; //listofGames;

        }
        #endregion

        #region Get Category by Game
        public Category GetCategoryByGame(int gameId)
        {
            CategorytoGame relation = (from x in db.CategorytoGames
                                       where x.gameid == gameId
                                       select x).Single();
            Category returnCategory = (from x in db.Categories
                                       where x.id == relation.categoryid
                                       select x).Single();
            return returnCategory;
        }
        #endregion 

        #region Get Category By Id
        public Category GetCategoryById(int id)
		{
			Category myCategory = (from x in db.Categories
								   where x.id == id
								   select x).SingleOrDefault();
			return myCategory;
		}
        #endregion 

        #region Add Game
        public void AddNewGame(Game newGame)
        {
            db.Games.InsertOnSubmit(newGame);
            db.SubmitChanges();
            
        }
        #endregion

        #region Add New Game To Category
        public void AddNewGameToCategory(int categoryId, int gameId)
        {
            //Creating a newRelationship
            CategorytoGame newRelationship = new CategorytoGame
            {
                categoryid = categoryId,
                gameid = gameId,
            };

            db.CategorytoGames.InsertOnSubmit(newRelationship);
            db.SubmitChanges();
        }
        #endregion

        #region Remove Game
        public void RemoveGame(Game Game)
        {
            var deleteGame = (from x in db.Games
                              where x.id == Game.id
                              select x).Single();

            var deleteGameFromCategory = (from x in db.CategorytoGames
                                          where x.gameid == Game.id
                                          select x).SingleOrDefault();

            db.CategorytoGames.DeleteOnSubmit(deleteGameFromCategory);
            db.Games.DeleteOnSubmit(deleteGame);
            db.SubmitChanges();
        }
        #endregion

        #region Update
        public void Update(Game newGame)
        {
            Game oldGame = (from x in db.Games
                                 where x.id == newGame.id
                                 select x).SingleOrDefault();

            //Updating the game
            oldGame = new Game
            {
                maxplayers = newGame.maxplayers,
                minplayers = newGame.minplayers,
                name = newGame.name,
                rating = newGame.rating,
                description = newGame.description,
                type = newGame.type,
                image = newGame.image
            };
               
            db.SubmitChanges();
        }
        #endregion

        #region Get All Categories
        public IEnumerable<Category> GetAllCategories()
        {
             var listofCategories = (from x in db.Categories
                                      select x);
             return listofCategories;
        }
        #endregion

        #region Add Active Game
        public void AddActiveGame(ActiveGame newActiveGame)
        {
                db.ActiveGames.InsertOnSubmit(newActiveGame);
                db.SubmitChanges();
        }
        #endregion

        #region Remove Active Game
        public void RemoveActiveGame(int Id)
        {
            ActiveGame tempActiveGame = (from x in db.ActiveGames
                                          where x.id == Id
                                          select x).SingleOrDefault();

            db.ActiveGames.DeleteOnSubmit(tempActiveGame);
            db.SubmitChanges();
        }
        #endregion

        #region Get Active Game by Id
        public ActiveGame GetActiveGameById(int id)
        {
            ActiveGame activeGameById = (from x in db.ActiveGames
                                          where x.id == id
                                          select x).SingleOrDefault();
           
            return activeGameById;
        }
        #endregion

        #region Update
        public void Update(ActiveGame updateForActiveGame)
        {
            ActiveGame activeGameToBeUpdated = (from x in db.ActiveGames
                                                where x.id == updateForActiveGame.id
                                                select x).SingleOrDefault();
            //If the maxplayer count has been reached the game will be closed
            //if (activeGameToBeUpdated.maxplayers == updateForActiveGame.numberofplayers)
            //{
            //    updateForActiveGame.open = false;
            //    return;
            //}

            //Upadating the Game
            activeGameToBeUpdated = new ActiveGame
            {
                id = updateForActiveGame.id,
                gameid = updateForActiveGame.gameid,
                gametime = updateForActiveGame.gametime,
                playertime = updateForActiveGame.playertime,
                numberofplayers = updateForActiveGame.numberofplayers,
                open = updateForActiveGame.open,
                owner = updateForActiveGame.owner,
                decription = updateForActiveGame.decription
            };
            db.SubmitChanges();
        }
        #endregion

        #region  Get All Active Game
        public IEnumerable<ActiveGame> GetAllActiveGames()
        {
            var listOfActiveGames = from x in db.ActiveGames
                                    select x;
            
            return listOfActiveGames;
        }
        #endregion

        #region Get Active Games Of by Type
        public IEnumerable<ActiveGame> GetActiveGamesOfType(int GameId)
        {
            var ListOfActiveGames = from x in db.ActiveGames
                                    where x.gameid == GameId
                                    select x;
            
            return ListOfActiveGames;

        }
        #endregion

        #region Get Id By Owner
        public int GetIdByOwner(ActiveGame ActiveGame)
        {
            ActiveGame Game = (from x in db.ActiveGames
                                where x.owner == ActiveGame.owner
                                select x).SingleOrDefault();
            if (Game == null)
            {
                //If the Game is not it will return the id -1
                ActiveGame tempGame = new ActiveGame
                {
                    id = -1
                };

                return tempGame.id;
            }

            return Game.id;
        }
        #endregion

        #region Owner has Game
        public bool OwnerHasGame(String Owner)
        {
            try
            {
                var Active = (from x in db.ActiveGames
                              where x.owner == Owner
                              select x).First();
                return true;
            }
            catch 
            {
                return false;
            }
            
        }
        #endregion

        #region RatingSystem
        #region Get Rating
        public GameRating GetRating(int gameId, int userId)
		{
			GameRating myRating = (from x in db.GameRatings
								   where x.GameID == gameId && x.UserID == userId
								   select x).SingleOrDefault();
			return myRating;
		}
        #endregion

        #region Add Rating
        public void AddRating(double rating, int gameId, int userId)
        {
			GameRating gameRater = new GameRating()
            {
				UserID = userId,
				GameID = gameId,
				Rating = rating,
            };

			db.GameRatings.InsertOnSubmit(gameRater);
			db.SubmitChanges();

			double newRating = (from x in db.GameRatings
							 where x.GameID == gameId
							 select x.Rating).Average();

			newRating = Math.Round(newRating, 2);

			Game gameRated = GetGameById(gameId);

			gameRated.rating = newRating;

			db.SubmitChanges();

		}
        #endregion

        #region Get Rating of Game
        public IEnumerable<GameRating> GetRatingofGame(int gameId)
        {
            var listOfRatings = (from x in db.GameRatings
                                 where x.GameID == gameId
                                 select x);
            return listOfRatings;
        }
        #endregion

        #endregion
    }
}